package com.pvj.textimagetitlelibrary;


import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.TextTool;
import ohos.app.Context;
import ohos.biometrics.authentication.IFaceAuthentication;

//https://cloud.tencent.com/developer/article/1740649
//https://harmonyos.51cto.com/posts/8855
public class TextImageTitle extends DirectionalLayout implements Component.EstimateSizeListener {
    private static final String TAG = "TextImageTitle";

    public final static int LAYOUT_FRONT = 0;
    public final static int LAYOUT_TAIL = 1;


    private Paint measurePaint;
    private String title;


    private static final int DEFAULT_LINES = 1;


    public TextImageTitle(Context context) {
        this(context, null);
    }

    public TextImageTitle(Context context, AttrSet attrSet) {
        this(context, attrSet, "");
    }

    public TextImageTitle(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init(context);
    }


    private void init(Context context) {
        setOrientation(ComponentContainer.VERTICAL);
        measurePaint = new Paint();
        // 设置测量组件的侦听器
        setEstimateSizeListener(this);

    }

    private <T extends Component> T findViewById(Component component, int id) {
        return (T) component.findComponentById(id);
    }

    private Parameter parameter;

    public void setParameter(Parameter parameter) {
        this.parameter = parameter;
    }


    public void setText(String title) {
        L.d(TAG, "setText title:" + title);
        if (title == null) return;
        this.title = title;

        //invalidate(); 无效
        // 该用这种方式
        removeAllComponents();
    }


    private ImageClickedListener listener;

    public void setImageClickedListener(ImageClickedListener listener) {
        this.listener = listener;
    }

    private int mEstimateSizeWidth = 0;

    @Override
    public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {
        int width = EstimateSpec.getSize(widthEstimateConfig);
        mEstimateSizeWidth = width;
        L.d(TAG, "onEstimateSize width : " + mEstimateSizeWidth);
        L.d(TAG, "onEstimateSize title : " + title);
        textCalculate();

        return false;
    }


    private void textCalculate() {
        if (title == null) return;
        int lineWidth = mEstimateSizeWidth;
        L.d(TAG, "lineWidth:" + lineWidth);
        int titleLength = title.length();
        L.d(TAG, "titleLength:" + titleLength);
        measurePaint.setTextSize(parameter.textSize);

        int curLines = 1;
        float curWidth = 0.0f;
        int indexEnd = 0;

        boolean isFront = parameter.imageLayout == LAYOUT_FRONT;

        // 图片参数
        int imageTotalWidth = parameter.imageWidth + parameter.imageMarginLeft + parameter.imageMarginRight;
        L.d(TAG, "image imageTotalWidth : " + imageTotalWidth);

        for (int index = 0; index < titleLength; index++) {
            String c = String.valueOf(title.charAt(index));
            float vW = measurePaint.measureText(c);
            curWidth += vW;

            if (parameter.maxTextLines != -1) {
                if (parameter.maxTextLines == curLines) { // 进入最后一行
                    if (!isFront || parameter.maxTextLines == 1) {
                        String endText = title.substring(indexEnd, titleLength);
                        int maxTextWidth = lineWidth - imageTotalWidth;
                        createTextAndImage(endText, maxTextWidth, isFront);
                        break;
                    } else {
                        String endText = title.substring(indexEnd, titleLength);
                        createText(endText);
                        break;
                    }
                } else {
                    if (isFront && curLines == 1) {
                        if (lineWidth < curWidth + imageTotalWidth) {
                            String curText = title.substring(indexEnd, index);
                            indexEnd = index;
                            int maxTextWidth = lineWidth - imageTotalWidth;
                            createTextAndImage(curText, maxTextWidth, isFront);
                            curLines++;
                            curWidth = 0.0f;
                        }
                    } else if (lineWidth < curWidth) {
                        String curText = title.substring(indexEnd, index);
                        indexEnd = index;
                        createText(curText);
                        curLines++;
                        curWidth = 0.0f;
                    }

                    if (index == titleLength - 1) {
                        if (!isFront) {
                            String endText = title.substring(indexEnd, titleLength);
                            if (lineWidth < curWidth + imageTotalWidth) {
                                createText(endText);
                                int maxTextWidth = lineWidth - imageTotalWidth;
                                createTextAndImage("", maxTextWidth, isFront);
                            } else {
                                int maxTextWidth = lineWidth - imageTotalWidth;
                                createTextAndImage(endText, maxTextWidth, isFront);
                            }
                        } else {
                            String endText = title.substring(indexEnd, titleLength);
                            createText(endText);
                        }
                    }

                }
            } else {
                //无限制
                if (isFront && curLines == 1) {
                    if (lineWidth < curWidth + imageTotalWidth) { // 小于一个字符的宽度
                        curLines++;
                        curWidth = 0.0f;
                        String curText = title.substring(indexEnd, index);
                        indexEnd = index;
                        int maxTextWidth = lineWidth - imageTotalWidth;
                        createTextAndImage(curText, maxTextWidth, isFront);
                    }
                }
                if (lineWidth < curWidth) { // 小于一个字符的宽度
                    String curText = title.substring(indexEnd, index);
                    createText(curText);
                    curLines++;
                    curWidth = 0.0f;
                    indexEnd = index;
                    // 到了最后一个index

                    if (titleLength - 1 == index) {
                        String endText = title.substring(indexEnd, index + 1);
                        int maxTextWidth = lineWidth - imageTotalWidth;
                        createTextAndImage(endText, maxTextWidth, isFront);
                    }

                } else {
                    // 到了最后一个index
                    if (titleLength - 1 == index) {
                        if (isFront) {
                            String endText = title.substring(indexEnd, titleLength);
                            createText(endText);
                            break;
                        } else {
                            String endText = title.substring(indexEnd, index + 1);
                            if (lineWidth < curWidth + imageTotalWidth) {
                                createText(endText);
                                curLines++;
                                int maxTextWidth = lineWidth - imageTotalWidth;
                                createTextAndImage("", maxTextWidth, isFront);
                            } else {
                                int maxTextWidth = lineWidth - imageTotalWidth;
                                createTextAndImage(endText, maxTextWidth, isFront);
                            }
                        }

                    }
                }
            }
        }
    }

    private void createTextAndImage(String text, int maxTextWidth, boolean isFront) {
        L.d(TAG, "createTextAndImage+:" + text);
        DirectionalLayout directionalLayout = new DirectionalLayout(getContext());
        directionalLayout.setOrientation(ComponentContainer.HORIZONTAL);
        directionalLayout.setAlignment(LayoutAlignment.VERTICAL_CENTER);
        Text titleText = new Text(getContext());
//        ShapeElement shapeElement = new ShapeElement();
//        shapeElement.setRgbColor(RgbColor.fromArgbInt(0xffff00ff));
//        titleText.setBackground(shapeElement);
        titleText.setTextSize(parameter.textSize);
        titleText.setTextColor(parameter.textColor);
        titleText.setMaxTextWidth(maxTextWidth);
        titleText.setMultipleLine(false);
        titleText.setTruncationMode(Text.TruncationMode.ELLIPSIS_AT_END);
        titleText.setText(text);

        Component component = getImage(text);
        component.setClickedListener(new ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (listener != null) {
                    listener.onClick();
                }
            }
        });

        if (isFront) {
            if (component != null) {
                directionalLayout.addComponent(component);
            }
            directionalLayout.addComponent(titleText, ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
        } else {
            directionalLayout.addComponent(titleText, ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
            if (component != null) {
                directionalLayout.addComponent(component);
            }
        }
        addComponent(directionalLayout, ComponentContainer.LayoutConfig.MATCH_PARENT, parameter.lineHeight);
    }

    private Component getImage(String text) {
        if (parameter.imageComponent != null) {
            parameter.imageComponent.setComponentSize(parameter.imageWidth, parameter.imageHeight);
            parameter.imageComponent.setMarginLeft(parameter.imageMarginLeft);
            parameter.imageComponent.setMarginRight(parameter.imageMarginRight);
            return parameter.imageComponent;
        } else if (parameter.imageResId != 0) {
            Image image = new Image(getContext());
            image.setComponentSize(parameter.imageWidth, parameter.imageHeight);
            if (!TextTool.isNullOrEmpty(text)) {
                image.setMarginLeft(parameter.imageMarginLeft);
                image.setMarginRight(parameter.imageMarginRight);
            }
            image.setScaleMode(Image.ScaleMode.STRETCH);
            image.setPixelMap(parameter.imageResId);
            return image;
        }
        return null;
    }

    private void createText(String text) {
        L.d(TAG, "createText+:" + text);
        Text titleText = new Text(getContext());
        titleText.setTextSize(parameter.textSize);
        titleText.setTextColor(parameter.textColor);
//        ShapeElement shapeElement = new ShapeElement();
//        shapeElement.setRgbColor(RgbColor.fromArgbInt(0xff0000ff));
//        titleText.setBackground(shapeElement);
        addComponent(titleText, ComponentContainer.LayoutConfig.MATCH_PARENT, parameter.lineHeight);
        titleText.setText(text);
    }


    public interface ImageClickedListener {
        void onClick();
    }

    public static class Parameter {
        private int textSize = 45;
        private Color textColor = new Color(0xff000000);

        private int lineHeight = 60;

        private int maxTextLines = DEFAULT_LINES;
        private int imageLayout;
        private int imageResId;
        private int imageWidth;
        private int imageHeight;
        private int imageMarginLeft;
        private int imageMarginRight;
        private Component imageComponent;


        public int getLineHeight() {
            return lineHeight;
        }

        public Parameter setLineHeight(int lineHeight) {
            this.lineHeight = lineHeight;
            return this;
        }

        public Color getTextColor() {
            return textColor;
        }

        public Parameter setTextColor(Color textColor) {
            this.textColor = textColor;
            return this;
        }

        public int getTextSize() {
            return textSize;
        }

        public Parameter setTextSize(int textSize) {
            this.textSize = textSize;
            return this;
        }


        public int getMaxTextLines() {
            return maxTextLines;
        }

        public Parameter setMaxTextLines(int maxTextLines) {
            if (maxTextLines <= 0) {
                maxTextLines = -1;
            }
            this.maxTextLines = maxTextLines;
            return this;
        }

        public int getImageLayout() {
            return imageLayout;
        }

        public Parameter setImageLayout(int imageLayout) {
            this.imageLayout = imageLayout;
            return this;
        }

        public int getImageResId() {
            return imageResId;
        }

        public Parameter setImageResId(int imageResId) {
            this.imageResId = imageResId;
            return this;
        }

        public int getImageWidth() {
            return imageWidth;
        }

        public Parameter setImageWidth(int imageWidth) {
            this.imageWidth = imageWidth;
            return this;
        }

        public int getImageHeight() {
            return imageHeight;
        }

        public Parameter setImageHeight(int imageHeight) {
            this.imageHeight = imageHeight;
            return this;
        }

        public int getImageMarginLeft() {
            return imageMarginLeft;
        }

        public Parameter setImageMarginLeft(int imageMarginLeft) {
            this.imageMarginLeft = imageMarginLeft;
            return this;
        }

        public int getImageMarginRight() {
            return imageMarginRight;
        }

        public Parameter setImageMarginRight(int imageMarginRight) {
            this.imageMarginRight = imageMarginRight;
            return this;
        }

        public Component getImageComponent() {
            return imageComponent;
        }

        public Parameter setImageComponent(Component imageComponent) {
            this.imageComponent = imageComponent;
            return this;
        }
    }
}
